"""
Sora2视频生成处理器
处理Web请求并调用TikHub Sora2视频生成器
"""

import os
import uuid
import json
import threading
import time
import sqlite3
from typing import Optional, Dict, Any
from flask import request, jsonify, send_file, current_app
from src.processors.tikhub_sora2_video import TikHubSora2VideoGenerator
from src.utils.video_database import VideoDatabase


class Sora2VideoHandler:
    """Sora2视频生成处理器"""
    
    def __init__(self):
        """初始化处理器"""
        self.generator = TikHubSora2VideoGenerator()
        self.db = VideoDatabase()
        self.tasks = {}  # 任务状态存储
    
    def generate_video(self):
        """
        处理视频生成请求
        """
        try:
            # 获取表单数据
            mode = request.form.get('mode', 'text')  # text 或 image
            prompt = request.form.get('prompt', '')
            orientation = request.form.get('orientation', 'portrait')
            
            if not prompt:
                return jsonify({
                    'success': False,
                    'error': '视频描述不能为空'
                }), 400
            
            # 创建任务ID
            task_id = f"sora2_{uuid.uuid4().hex}"
            
            # 初始化任务状态
            self.tasks[task_id] = {
                'status': 'initialized',
                'progress': 0,
                'prompt': prompt,
                'orientation': orientation,
                'mode': mode,
                'video_url': None,
                'download_url': None,
                'error': None,
                'tikhub_task_id': None  # 添加TikHub任务ID字段
            }
            
            # 在后台线程中执行视频生成
            thread = threading.Thread(
                target=self._process_video_generation,
                args=(task_id, mode, prompt, orientation)
            )
            thread.daemon = True
            thread.start()
            
            return jsonify({
                'success': True,
                'task_id': task_id
            })
            
        except Exception as e:
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    def _process_video_generation(self, task_id: str, mode: str, prompt: str, orientation: str):
        """
        在后台线程中处理视频生成
        
        Args:
            task_id (str): 任务ID
            mode (str): 生成模式 (text/image)
            prompt (str): 视频描述
            orientation (str): 视频方向
        """
        try:
            # 更新任务状态
            self.tasks[task_id]['status'] = 'uploading' if mode == 'image' else 'creating'
            self.tasks[task_id]['progress'] = 0.1
            
            media_id: Optional[str] = None
            # 如果是图片模式，需要先上传图片
            if mode == 'image':
                if 'image' in request.files:
                    image_file = request.files['image']
                    if image_file.filename != '':
                        # 保存图片到临时文件
                        temp_path = os.path.join('data', 'images', f"temp_{uuid.uuid4().hex}_{image_file.filename}")
                        image_file.save(temp_path)
                        
                        # 上传图片到TikHub
                        upload_result = self.generator.upload_image(temp_path)
                        if upload_result and 'id' in upload_result:
                            media_id = upload_result['id']
                            self.tasks[task_id]['progress'] = 0.3
                        else:
                            raise Exception("图片上传失败")
                        
                        # 删除临时文件
                        try:
                            os.remove(temp_path)
                        except:
                            pass
                else:
                    raise Exception("未提供图片文件")
            
            # 创建视频生成任务
            self.tasks[task_id]['status'] = 'creating'
            self.tasks[task_id]['progress'] = 0.4
            
            create_result = self.generator.create_video(
                prompt=prompt,
                orientation=orientation,
                media_id=media_id
            )
            
            print(f"创建视频任务返回结果: {create_result}")
            
            if not create_result:
                raise Exception("创建视频任务失败，返回结果为空")
            
            # 根据实际返回的数据结构提取任务ID
            # 从日志看，任务ID在data字段中
            if 'data' in create_result and 'id' in create_result['data']:
                task_id_tikhub = create_result['data']['id']
            elif 'id' in create_result:
                task_id_tikhub = create_result['id']
            else:
                raise Exception(f"创建视频任务失败，返回结果中缺少'id'字段: {create_result}")
            
            # 将TikHub任务ID存储到任务信息中
            self.tasks[task_id]['tikhub_task_id'] = task_id_tikhub
            self.tasks[task_id]['progress'] = 0.5
            print(f"获取到TikHub任务ID: {task_id_tikhub}")
            
            # 等待任务完成
            self.tasks[task_id]['status'] = 'processing'
            
            # 轮询任务状态
            while True:
                status_result = self.generator.get_task_status(task_id_tikhub)
                print(f"任务状态查询返回结果: {status_result}")
                
                if not status_result:
                    raise Exception("获取任务状态失败，返回结果为空")
                
                if 'status' not in status_result:
                    raise Exception(f"获取任务状态失败，返回结果中缺少'status'字段: {status_result}")
                
                status = status_result.get('status')
                # 处理progress_pct为None的情况
                progress = status_result.get('progress_pct') or 0
                
                # 更新进度 (50% - 90%)
                self.tasks[task_id]['progress'] = 0.5 + (progress * 0.4)
                
                if status == 'succeeded':
                    # 任务成功完成
                    self.tasks[task_id]['status'] = 'downloading'
                    self.tasks[task_id]['progress'] = 0.9
                    print("任务成功完成，准备获取生成详情")
                    
                    # 获取生成详情
                    generations = status_result.get('generations') or []
                    if not generations:
                        raise Exception(f"任务成功完成但返回结果中缺少'generations'字段或为空: {status_result}")
                    
                    generation_id = generations[0]['id']
                    print(f"获取到Generation ID: {generation_id}")
                    
                    detail_result = self.generator.get_task_detail(generation_id=generation_id)
                    print(f"获取任务详情返回结果: {detail_result}")
                    
                    if not detail_result or 'post' not in detail_result:
                        raise Exception(f"获取视频详情失败: {detail_result}")
                    
                    # 获取视频链接
                    if 'attachments' not in detail_result['post'] or not detail_result['post']['attachments']:
                        raise Exception(f"获取视频详情失败，返回结果中缺少'attachments'字段或为空: {detail_result}")
                    
                    video_url = detail_result['post']['attachments'][0]['url']
                    download_url = detail_result['post']['attachments'][0]['downloadable_url']
                    print(f"获取到视频URL: {video_url}")
                    print(f"获取到下载URL: {download_url}")
                    
                    # 保存视频到本地
                    import datetime
                    import os
                    
                    # 创建按日期组织的目录结构
                    today = datetime.datetime.now().strftime("%Y%m%d")
                    sora2_dir = os.path.join('data', 'videos', today, 'sora2')
                    os.makedirs(sora2_dir, exist_ok=True)
                    
                    video_filename = f"sora2_{uuid.uuid4().hex}.mp4"
                    video_path = os.path.join(sora2_dir, video_filename)
                    print(f"准备保存视频到: {video_path}")
                    
                    # 下载视频
                    import requests
                    video_response = requests.get(video_url)
                    print(f"视频下载响应状态码: {video_response.status_code}")
                    if video_response.status_code == 200:
                        with open(video_path, 'wb') as f:
                            f.write(video_response.content)
                        print("视频下载完成")
                        
                        # 更新任务状态
                        self.tasks[task_id]['status'] = 'completed'
                        self.tasks[task_id]['progress'] = 1.0
                        # 修改URL路径以匹配新的目录结构
                        self.tasks[task_id]['video_url'] = f"/sora2/video/{today}/sora2/{video_filename}"
                        self.tasks[task_id]['download_url'] = f"/sora2/download/{today}/sora2/{video_filename}"
                        print(f"任务完成，视频URL: {self.tasks[task_id]['video_url']}")
                        
                        # 保存到数据库
                        self._save_sora2_video_info({
                            'task_id': task_id,
                            'prompt': prompt,
                            'orientation': orientation,
                            'video_path': video_path,
                            'status': 'completed'
                        })
                    else:
                        raise Exception("下载视频失败")
                    break
                    
                elif status == 'failed':
                    # 任务失败
                    error_msg = status_result.get('error', '任务执行失败')
                    self.tasks[task_id]['status'] = 'failed'
                    self.tasks[task_id]['error'] = error_msg
                    print(f"任务失败: {error_msg}")
                    break
                    
                # 等待2秒后继续轮询
                time.sleep(2)
                
        except Exception as e:
            # 更新任务状态为失败
            self.tasks[task_id]['status'] = 'failed'
            self.tasks[task_id]['error'] = str(e)
            print(f"视频生成失败: {e}")

    def _save_sora2_video_info(self, video_info: Dict[str, Any]):
        """
        保存Sora2视频信息到数据库
        
        Args:
            video_info (dict): 视频信息
        """
        try:
            with sqlite3.connect(self.db.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute("""
                    INSERT OR IGNORE INTO sora2_videos (
                        task_id, prompt, orientation, video_path, status
                    ) VALUES (?, ?, ?, ?, ?)
                """, (
                    video_info['task_id'], video_info['prompt'], 
                    video_info['orientation'], video_info['video_path'],
                    video_info['status']
                ))
                conn.commit()
        except Exception as e:
            print(f"保存Sora2视频信息到数据库时出错: {e}")
    
    def get_task_status(self, task_id: str):
        """
        获取任务状态
        
        Args:
            task_id (str): 任务ID
        """
        if task_id not in self.tasks:
            return jsonify({
                'success': False,
                'error': '任务不存在'
            }), 404
        
        task = self.tasks[task_id]
        return jsonify({
            'success': True,
            'task_id': task_id,
            'status': task['status'],
            'progress': task['progress'],
            'video_url': task['video_url'],
            'download_url': task['download_url'],
            'error': task['error']
        })
    
    def serve_video(self, filename: str):
        """
        提供视频文件服务
        
        Args:
            filename (str): 视频文件名（包含路径）
        """
        try:
            # 解析完整的文件路径
            video_path = os.path.join('data', 'videos', filename)
            if os.path.exists(video_path):
                return send_file(video_path)
            else:
                return jsonify({
                    'success': False,
                    'error': '视频文件不存在'
                }), 404
        except Exception as e:
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    def download_video(self, filename: str):
        """
        提供视频文件下载
        
        Args:
            filename (str): 视频文件名（包含路径）
        """
        try:
            # 解析完整的文件路径
            video_path = os.path.join('data', 'videos', filename)
            if os.path.exists(video_path):
                return send_file(video_path, as_attachment=True)
            else:
                return jsonify({
                    'success': False,
                    'error': '视频文件不存在'
                }), 404
        except Exception as e:
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500